<template>
    <div ref="all">
        <hyl-search :formType="searchType" :formColumns="searchColumns" :formColumnsRule="searchColumnsRule" :customColumnsData="customSearchColumnsData" v-on:getFormData="getSearchFormData"></hyl-search>
        <hyl-table :tableData="tableData" :columns="columns" :specialColumns="specialColumns" v-on:tableSelection="tableSelection">
            <template slot="buttons">
                <el-button type="text" v-if="buttonsVisible.edit.visible" icon="el-icon-edit" @click="handleClick({},'edit')">编辑</el-button>
                <el-button type="text" v-if="buttonsVisible.add.visible" icon="el-icon-circle-plus-outline" @click="handleClick({},'add')">添加</el-button>
                <el-button type="text" v-if="buttonsVisible.delete.visible" icon="el-icon-delete" @click="handleClick({},'delete')">删除</el-button>
                <el-button type="text" icon="el-icon-setting" @click="handleClick({},'grantRole')">角色授权</el-button>
            </template>
          <!-- 定制表格单元格所显示内容 -->
          <div slot="createTime" slot-scope="scope">{{scope.$row.createTime | dateString}}</div>
          <div slot="updateTime" slot-scope="scope">{{scope.$row.updateTime | dateString}}</div>
        </hyl-table>
        <hyl-pagination :total="total" v-on:fetch="fetch" :page-sizes="[5,10,15]"/>
        <!-- 增加,删除 对话框  start -->
        <el-dialog title="添加"  :visible="addDialogVisible" width="40%" :show-close="false" size="mini">
            <el-form ref="addForm" :model="addData" label-width="85px" status-icon :rules="addColumnsRule" size="mini">
              <el-form-item label="用户名:" prop="username">
                <el-input type="text" v-model="addData.username"  autocomplete="off" size="mini"></el-input>
              </el-form-item>
              <el-form-item label="别名:" prop="nickname">
                <el-input type="text" v-model="addData.nickname"  autocomplete="off" size="mini"></el-input>
              </el-form-item>
              <el-form-item label="密码" prop="password">
                <el-input type="password" v-model="addData.password"  autocomplete="off" size="mini"></el-input>
              </el-form-item>
              <el-form-item label="确认密码" prop ="rePassword">
                <el-input type="password" v-model="addData.rePassword"  autocomplete="off" size="mini"></el-input>
              </el-form-item>
              <el-form-item label="性别" prop="sex">
                <!--<el-input type="text" v-model="addData.sex"  autocomplete="off" size="mini"></el-input>-->
                <el-radio v-model="addData.sex" label="false" size="mini">男</el-radio>
                <el-radio v-model="addData.sex" label="true" size="mini">女</el-radio>
              </el-form-item>
            </el-form>
            <span slot="footer">
              <el-button type="text" @click="handleCancel('add')"><i class="fa fa-remove fa-fw">&nbsp;</i>取 消</el-button>
              <el-button type="text" @click="getAddFormData(addData,'add')"><i class="fa fa-plus fa-fw">&nbsp;</i>确 定</el-button>
            </span>
        </el-dialog>
        <el-dialog title="编辑" :visible.sync="editDialogVisible" width="40%">
            <hyl-form :formType="editType" :editData="editData" :formColumns="editColumns" :formColumnsRule="editColumnsRule" :customColumnsData="customEditColumnsData" v-on:getFormData="getEditFormData" v-on:handleCancel="handleCancel"></hyl-form>
        </el-dialog>
      <!-- :visible.sync 这样设置点叉可以叉掉, :visible="addDialogVisible 这样点叉是叉不掉的 -->
        <el-dialog title="角色授权" :visible.sync="grantRoleDialogVisible" width="40%" size="mini">
          <hyl-search :formType="dialogSearchType" :formColumns="dialogSearchColumns" v-on:getFormData="getDialogSearchFormData"></hyl-search>
          <div style="margin-top: 5px">
            <el-tag
              size="small"
              :key="select.id"
              v-for="select in dialogTagSelect"
              closable
              :disable-transitions="false"
              @close="handleTagClose(select)">
              {{select.code}}
            </el-tag>
          </div>
          <hyl-table :tableData="dialogTableData" :columns="dialogColumns" :specialColumns="specialColumns" v-on:tableSelection="dialogTableSelection">
            <template slot="buttons">
              <el-button type="text" icon="el-icon-setting" @click="handleDialogClick({},'grant')">授权</el-button>
              <el-button type="text" icon="el-icon-refresh" @click="handleDialogRefresh({},'')">刷新</el-button>
            </template>
            <!-- 定制表格单元格所显示内容 -->
            <div slot="createTime" slot-scope="scope">{{scope.$row.createTime | dateString}}</div>
            <div slot="updateTime" slot-scope="scope">{{scope.$row.updateTime | dateString}}</div>
          </hyl-table>
          <hyl-pagination :total="total" v-on:fetch="dialogFetch" :page-sizes="[5,10,15]"/>
        </el-dialog>
        <!-- 增加,删除 对话框  end -->
    </div>
</template>

<script>
import hylTable from '@/components/table'
import hylPagination from '@/components/pagination'
import hylForm from '@/components/form'
import hylSearch from '@/components/search'
import {fetch, del, post, put} from '@/utils/http'
import {mapGetters} from 'vuex'
export default {
  name: 'index',
  components: {
    hylTable,
    hylPagination,
    hylForm,
    hylSearch
  },
  data () {
    return {
      tableData: [],
      dialogTableData: [],
      total: 0,
      page: 1,
      limit: 5,
      dialogTotal: 0,
      dialogPage: 1,
      diaLogLimit: 5,
      specialColumns: [{
        type: 'selection',
        width: '55'
      }, {
        type: 'index',
        indexMethod: this.indexMethod
      }],
      columns: [{'prop': 'username', 'label': '用户名'},
        {'prop': 'nickname', 'label': '别名'},
        {'prop': 'headImgUrl', 'label': '头图片地址'},
        {'prop': 'phone', 'label': '手机', width: 108},
        {'prop': 'sex', 'label': '性别'},
        {'prop': 'isAble', 'label': '启用状态'},
        {'prop': 'type', 'label': '类型'},
        {'prop': 'createTime', 'label': '创建时间', width: 155},
        {'prop': 'updateTime', 'label': '修改时间', width: 155}],
      dialogColumns: [
        {'prop': 'code', 'label': 'code'},
        {'prop': 'name', 'label': '名称'}
      ],
      applicationName: '',
      controller: '',
      customAddColumnsData: {},
      addColumns: [
        {prop: 'username', label: '用户名', dataType: 'varchar'},
        {prop: 'nickname', label: '别名', dataType: 'varchar'},
        {prop: 'password', label: '密码', dataType: 'varchar'},
        {prop: 'rePassword', label: '重复密码', dataType: 'varchar'},
        {prop: 'sex', label: '性别', dataType: 'select', options: [{value: 0, label: '男'}, {value: 1, label: '女'}]}
      ],
      addColumnsRule: {
        username: [
          {required: true, message: '请输入用户名', trigger: 'blur'}, /// 这个是element自带配置的
          {validator: this.validateName, trigger: 'blur'} /// 自定义校验规则
        ],
        nickname: [
          {required: true, message: '请输入别名', trigger: 'blur'}, /// 这个是element自带配置的
          {validator: this.validateNickName, trigger: 'blur'} /// 自定义校验规则
        ],
        password: [
          {required: true, message: '请输入密码', trigger: 'blur'}, /// 这个是element自带配置的
          {validator: this.validatePassword, trigger: 'blur'} /// 自定义校验规则
        ],
        rePassword: [
          {required: true, message: '请输入密码', trigger: 'blur'}, /// 这个是element自带配置的
          {validator: this.validateRePassword, trigger: 'blur'} /// 自定义校验规则
        ]
      },
      addData: {
        username: '',
        nickname: '',
        password: '',
        rePassword: '',
        sex: ''
      },
      customEditColumnsData: {},
      editColumns: [
        {prop: 'username', label: '用户名', dataType: 'varchar'},
        {prop: 'nickname', label: '别名', dataType: 'varchar'},
        {prop: 'headImgUrl', label: '头图片地址', dataType: 'varchar'},
        {prop: 'phone', label: '手机', dataType: 'varchar'},
        {prop: 'sex', label: '性别', dataType: 'select', options: [{value: 1, label: '男'}, {value: 0, label: '女'}]},
        {prop: 'isAble', label: '启用状态', dataType: 'select', options: [{value: 0, label: '禁用'}, {value: 1, label: '启用'}]},
        {prop: 'type', label: '类型', dataType: 'select', options: [{value: 'APP', label: 'APP'}, {value: 'BACKEND', label: 'BACKEND'}]}
      ],
      editColumnsRule: {},
      editType: 'edit',
      editData: {},
      customSearchColumnsData: {},
      searchColumns: [
        {'prop': 'username', 'label': '用户名', dataType: 'varchar'}
      ],
      searchColumnsRule: {},
      cacheSearchData: {},
      dialogCacheSearchData: {},
      searchType: 'search',
      dialogSearchType: 'dialogSearch',
      multipleSelection: [],
      multipleDialogSelection: [],
      editDialogVisible: false,
      addDialogVisible: false,
      grantRoleDialogVisible: false,
      grantData: {},
      grantRoleData: {},
      dialogSearchColumns: [
        {'prop': 'code', 'label': 'code', dataType: 'varchar'},
        {'prop': 'name', 'label': '名称', dataType: 'varchar'}
      ],
      dialogTagSelect: [],
      buttonsVisible: {
        add: {'security': 'back:user:save', visible: true},
        edit: {'security': 'back:user:update', visible: true},
        delete: {'security': 'back:user:delete', visible: true}
      }
    }
  },
  mounted: function () {
    this.getColumns()
    this.fetch()
    // this.dialogFetch()

    this.buttonsVisible.add.visible = false
    this.buttonsVisible.edit.visible = false
    this.buttonsVisible.delete.visible = false
    this.resources.forEach((item) => {
      if (item === this.buttonsVisible.add.security) {
        console.log('this.buttonsVisible.add.visible')
        this.buttonsVisible.add.visible = true
      }
      if (item === this.buttonsVisible.edit.security) {
        console.log('this.buttonsVisible.edit.visible')
        this.buttonsVisible.edit.visible = true
      }
      if (item === this.buttonsVisible.delete.security) {
        console.log('this.buttonsVisible.delete.visible')
        this.buttonsVisible.delete.visible = true
      }
    })
  },
  computed: {
    ...mapGetters(['resources'])
  },
  watch: {
    multipleDialogSelection: function (val, oldVal) {
      console.log('watch:' + val)
      if (this.dialogTagSelect.length === 0) {
        this.dialogTagSelect.push(...val)
      } else {
        /// 去重
        val.forEach((item) => {
          let b = true
          this.dialogTagSelect.forEach((select) => {
            if (item.id === select.id) {
              b = false
            }
          })
          if (b) {
            this.dialogTagSelect.push(item)
          }
        })
      }
    }
  },
  methods: {
    handleTagClose (select) {
      if (this.dialogTagSelect.length > 0) {
        this.dialogTagSelect.forEach((item, index) => {
          if (select.id === item.id) {
            /// 从当前索引删除一个元素
            this.dialogTagSelect.splice(index, 1)
          }
        })
      }
    },
    handleDialogRefresh () {
      this.dialogFetch()
    },
    handleClick (row = {}, type = '') {
      switch (type) {
        case 'add':
          // 显示添加数据对话框
          this.addDialogVisible = true
          // 如查要对数据进行处理,在此进行,如:datetime类型
          /// 数据处理完后,赋值操作
          this.addData = row
          // alert('add')
          break
        case 'delete':
          // 一行或多行删除操作
          if (this.multipleSelection.length > 0) {
            // 此处生成写法是默认数据库表中字段id为唯一key值,name这一行记录名称(方便知道删除的是神马!))
            let ids = ''
            let names = ''
            this.multipleSelection.forEach((selection) => {
              ids = ids + selection.id + ','
              names = names + selection.username + ','
            })
            this.$confirm(names + '确定要删除, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              this.delete(this.applicationName + '/' + this.controller + '/deleteBatch', {params: {ids: ids.slice(0, ids.length - 1)}})
            }).catch(() => {
              this.$message({
                type: 'info',
                message: '取消操作!'
              })
            })
          } else {
            /// 不符合条件
            this.$confirm('此操作需要至少选中一行, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).catch(() => {
              this.$message({
                type: 'info',
                message: '取消操作!'
              })
            })
          }
          // alert('删除')
          break
        case 'edit':
          /// 判断是否选中一行,其它情况都不符合要求
          if (this.multipleSelection.length === 1) {
            this.editData = this.multipleSelection[0]
            /// 显示编辑对话框
            this.editDialogVisible = true
          } else {
            this.$confirm('此操作只能选中一行, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).catch(() => {
              this.$message({
                type: 'info',
                message: '取消操作!'
              })
            })
          }
          // alert('edit')
          break
        case 'grantRole':
          /// 判断是否选中一行,其它情况都不符合要求
          if (this.multipleSelection.length === 1) {
            /// 显示授权角色对话框
            this.grantRoleDialogVisible = true
            this.grantData = this.multipleSelection[0]
            /// 显示之前再获取一下这个用户所有的角色
            fetch('upms/user/getRoleByUserId', {userId: this.grantData.id}).then((res) => {
              if (res.status === 200) {
                this.multipleDialogSelection = res.data
                // if (res.data !== null && res.data.length > 0) {
                //   res.data.forEach((item) => { this.multipleDialogSelection.push(item) })
                // }
                // console.log(this.multipleDialogSelection)
              } else {
                this.$message.error(`错误信息:${res.message}`)
              }
            })
            console.log(this.$refs.all)
          } else {
            this.$confirm('此操作只能选中一行, 是否继续?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).catch(() => {
              this.$message({
                type: 'info',
                message: '取消操作!'
              })
            })
          }
          break
        default:
          alert('其它操作')
      }
    },
    handleDialogClick (row = {}, type = '') {
      let dialogTagSelect = this.dialogTagSelect
      if (dialogTagSelect.length > 0) {
        /// 可以继续往下执行
        /// 1.解析出选中的用户id
        // let userId = this.grantData.id
        /// 先解析出授权的角色id
        let roleIdArr = []
        dialogTagSelect.forEach((item) => {
          roleIdArr.push(item.id)
        })
        let roleIds = roleIdArr.join(',')
        post(this.applicationName + '/user/grantRole', {
          userId: this.grantData.id,
          roleIds
        }).then((res) => {
          if (res.status === 200) {
            this.$message.success(res.message)
            /// 关闭对话框
            this.grantRoleDialogVisible = false
          } else {
            this.$message.error(res.message)
          }
        })
      } else {
        this.$message.warning('需要至少选中一数据!')
      }
    },
    handleCancel (type = '') {
      switch (type) {
        case 'add':
          this.addDialogVisible = false
          break
        case 'edit':
          this.editDialogVisible = false
          break
        default:
          alert('此对话框类型:+ type +不存,请查看代码')
          break
      }
    },
    indexMethod (index) {
      return index + 1 + (this.page - 1) * this.limit
    },
    tableSelection (val) {
      this.multipleSelection = val
    },
    dialogTableSelection (val) {
      this.multipleDialogSelection = val
    },
    fetch (page = {
      page: 1,
      limit: this.limit
    }) {
      Object.assign(page, this.cacheSearchData)
      fetch(this.applicationName + '/' + this.controller + '/page', page).then((res) => {
        if (res.status === 200) {
          this.tableData = res.data.rows
          this.total = res.data.total
          this.page = page.page
          this.limit = page.limit
        } else {
          this.$message.error(res.message)
        }
      })
    },
    dialogFetch (page = {
      page: 1,
      limit: this.limit
    }) {
      Object.assign(page, this.dialogCacheSearchData)
      fetch(this.applicationName + '/role/page', page).then((res) => {
        if (res.status === 200) {
          this.dialogTableData = res.data.rows
          this.dialogTotal = res.data.total
          this.dialogPage = page.page
          this.diaLogLimit = page.limit
        } else {
          this.$message.error(res.message)
        }
      })
    },
    delete (url, params) {
      del(url, params).then((res) => {
        this.$message.success('删除成功!')
        /// 刷新页面
        this.fetch()
      })
    },
    getColumns () {
      // var temp = [{'columnName': 'username', 'dataType': 'varchar'}, {'columnName': 'nickname', 'dataType': 'varchar'}, {'columnName': 'headImgUrl', 'dataType': 'varchar'}, {'columnName': 'phone', 'dataType': 'varchar'}, {'columnName': 'sex', 'dataType': 'tinyint'}, {'columnName': 'enabled', 'dataType': 'tinyint'}, {'columnName': 'type', 'dataType': 'varchar'}, {'columnName': 'createTime', 'dataType': 'datetime'}, {'columnName': 'updateTime', 'dataType': 'datetime'}]
      this.applicationName = 'upms'
      this.controller = 'user'
      // temp.forEach(item => {
      //   var obj = {}
      //   obj.prop = item.columnName
      //   obj.label = item.columnName
      //   this.columns.push(obj)
      // })
      // console.log(JSON.stringify(this.columns))
    },
    getSearchFormData (formData = {}, type, refs) {
      console.log(formData)
      console.log(type)
      this.cacheSearchData = formData
      /// 若formData数据为空,那么直接返回
      if (JSON.stringify(formData) === '{}') {
        return
      }
      /// searchForm做整体校验,通过提交
      refs['searchForm'].validate((valid) => {
        if (valid) {
          /// 提交
          let page = {
            limit: this.limit,
            page: this.page
          }
          /// 将formData对象赋给page对象
          Object.assign(page, formData)
          /// 模糊查询提交
          this.fetch(page)
        }
      })
    },
    getDialogSearchFormData (formData = {}, type) {
      console.log(formData)
      console.log(type)
      this.dialogCacheSearchData = formData
      /// 若formData数据为空,那么直接返回
      if (JSON.stringify(formData) === '{}') {
        this.dialogFetch()
        return
      }
      /// 提交
      let page = {
        limit: this.diaLogLimit,
        page: this.dialogPage
      }
      /// 将formData对象赋给page对象
      Object.assign(page, formData)
      /// 模糊查询提交
      this.dialogFetch(page)
    },
    getAddFormData (formData = {}, type, refs) {
      console.log(formData)
      console.log(type)
      /// 若formData数据为空,那么直接返回
      if (JSON.stringify(formData) === '{}') {
        return
      }
      /// addForm做整体校验,通过提交
      this.$refs['addForm'].validate((valid) => {
        if (valid) {
          /// 提交
          formData['enabled'] = true
          formData['type'] = 'APP'
          post(this.applicationName + '/' + this.controller + '/add', formData).then((res) => {
            if (res.status === 200) {
              this.$message.success('添加成功!')
              this.addDialogVisible = false
              this.$refs['addForm'].resetFields()
              this.fetch()
            } else {
              this.$message.info(res.message)
            }
          })
        }
      })
    },
    getEditFormData (formData = {}, type, refs) {
      console.log(formData)
      console.log(type)
      /// 若formData数据为空,那么直接返回
      if (JSON.stringify(formData) === '{}') {
        return
      }
      /// editForm提交
      put(this.applicationName + '/' + this.controller + '/update', formData).then((res) => {
        if (res.status === 200) {
          const h = this.$createElement
          this.$message({
            message: h('p', null, [
              h('i', { style: 'color: teal' }, '更新成功!')
            ])
          })
          this.editDialogVisible = false
          this.fetch()
        } else {
          this.$message.info(res.message)
        }
      })
    },
    // 下面的全是字段校验方法
    validateName (rule, value, callback) {
      // 只能存在中文与字母
      let pattern = /^[A-Za-z]{4,16}$/
      if (pattern.test(value)) {
        callback()
      } else {
        callback(new Error('请输入[4-16]位字母!'))
      }
    },
    validateNickName (rule, value, callback) {
      // 只能存在中文与字母
      let pattern = /^[\u4e00-\u9fa5A-Za-z]{4,16}$/
      if (pattern.test(value)) {
        callback()
      } else {
        callback(new Error('请输入[4-16]位字母中文!'))
      }
    },
    validatePassword (rule, value, callback) {
      // 只能存在中文与字母
      let pattern = /^[@!#$%^&*()-+_?,.A-Za-z0-9]{6,16}$/
      if (pattern.test(value)) {
        if (this.addData.password !== '') {
          this.$refs.addForm.validateField('rePassword')
        }
        callback()
      } else {
        callback(new Error('请输入[6-16]位@!#$%^&*()-+_?,.A-Za-z0-9'))
      }
    },
    validateRePassword (rule, value, callback) {
      console.log('this.formColumnsData.password:' + this.addData.password)
      // 只能存在中文与字母
      if (value !== this.addData.password) {
        callback(new Error('两次输入密码不一致,请检查!'))
      } else {
        callback()
      }
    }
  }
}
</script>

<style scoped>

</style>
